/*
 * Copyright (c) 2012 Tomas Shestakov. <http://code.google.com/p/jmmo/>
 */

package jmmo.engine.property

/**
 * Implements [[jmmo.engine.property.Binding]] trait for unlimited number of properties
 * form which depended some [[jmmo.engine.property.BoundProperty]].
 * Type of this parent properties is not known at compile time.
 * @param formula a predicate which gets sequence of properties values and returns calculated the `Binding` value
 * @param props a sequence of `Property`s from which the `Binding` depends
 * @tparam R type of `Binding` value
 * @author Tomas Shestakov
*/
class BindingSeq[R](formula: (Seq[_]) => R, props: Property[_]*) extends Binding[R] {

  def apply(): R = formula(props map (_()))

  def dependencies = props
}

/**
 * Contains factory methods to create instances of [[jmmo.engine.property.BindingSeq]].
 */
object BindingSeq {

  /**
   * Creates `Binding` for unlimited number of properties
   * form which depended some [[jmmo.engine.property.BoundProperty]]
   * Type of this parent properties is not known at compile time.
   * @param formula a predicate which gets sequence of properties values and returns calculated the `Binding` value
   * @param props a sequence of `Property`s from which the `Binding` depends
   * @tparam R type of `Binding` value
   * @return new instance of class extended from [[jmmo.engine.property.Binding]]
   */
  def apply[R](formula: (Seq[_]) => R, props: Property[_]*) = new BindingSeq[R](formula, props: _*)
}